package frontend.pages.admin.employee;

import backend.model.admin.CommuterData;
import backend.model.worklog.WorkLog;
import backend.service.admin.CommuterDataService;
import backend.service.worklog.WorkLogService;
import frontend.core.TimeTrackingWebApplication;
import frontend.model.admin.CommuterDataUIModel;
import shared.util.CalendarUtils;
import frontend.components.base.ComponentFactory;
import shared.other.TimePeriod;
import frontend.components.other.UserInputCallableAction;
import org.apache.wicket.Localizer;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.feedback.ContainerFeedbackMessageFilter;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;

import java.util.Collection;
import java.util.List;

public class CommuterDataForm extends Form {

    private CommuterDataUIModel model;
    protected FeedbackPanel feedbackPanel;

    public static final String RESOURCE_KEY_FIELD_LABEL_START_DATE = "pages.defaultReport.form.startDate";
    public static final String RESOURCE_KEY_FIELD_LABEL_END_DATE = "pages.defaultReport.form.endDate";
    private static final String RESOURCE_KEY_VALIDATION_EMPTY_COMMUTER_PERIOD_START_DATE = "validation.form.employee.emptyCommuterPeriodStartDate";
    private static final String RESOURCE_KEY_VALIDATION_EMPTY_COMMUTER_PERIOD_END_DATE = "validation.form.employee.emptyCommuterPeriodEndDate";
    private static final String RESOURCE_KEY_VALIDATION_EMPTY_COMMUTER_PERIOD_END_DATE_BEFORE_START_DATE = "validation.form.employee.emptyCommuterPeriodEndDateBeforeStartDate";
    private static final String RESOURCE_KEY_VALIDATION_EMPTY_COMMUTER_PERIOD_OVERLAPPING = "validation.form.employee.emptyCommuterPeriodOverlapping";
    private static final String RESOURCE_KEY_SAVE_SUCCESS = "info.entity.saved.successfully";

    public CommuterDataForm(String id, CommuterDataUIModel model, UserInputCallableAction postAddAction) {
        super(id);
        this.model = model;
        
        constructFormContent(postAddAction);
    }

    private void constructFormContent(final UserInputCallableAction postAddAction) {
        Panel startDate = ComponentFactory.createDatePickerComponent("startDate", RESOURCE_KEY_FIELD_LABEL_START_DATE, model);
        Panel endDate = ComponentFactory.createDatePickerComponent("endDate", RESOURCE_KEY_FIELD_LABEL_END_DATE, model);

        feedbackPanel = new FeedbackPanel("feedbackForAddCommuter");
        feedbackPanel.setFilter(new ContainerFeedbackMessageFilter(CommuterDataForm.this));
        feedbackPanel.setOutputMarkupId(true);

        AjaxButton saveCommutingPeriodButton = new AjaxButton("saveCommutingPeriod") {
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                if (isTimePeriodValid()) {
                    save();
                    postAddAction.call(target, null);
                    feedbackPanel.info(CalendarUtils.appendCurrentTime(Localizer.get().getString(RESOURCE_KEY_SAVE_SUCCESS, null)));
                }
                target.add(feedbackPanel);
            }

        };

        add(startDate, endDate, feedbackPanel, saveCommutingPeriodButton);

    }

    private boolean isTimePeriodValid() {
        if (model.getStartDate() == null) {
            feedbackPanel.error(Localizer.get().getString(RESOURCE_KEY_VALIDATION_EMPTY_COMMUTER_PERIOD_START_DATE, null));
            return false;
        }
        if (model.getEndDate() == null) {
            feedbackPanel.error(Localizer.get().getString(RESOURCE_KEY_VALIDATION_EMPTY_COMMUTER_PERIOD_END_DATE, null));
            return false;
        }
        if (model.getEndDate().before(model.getStartDate())) {
             feedbackPanel.error(Localizer.get().getString(RESOURCE_KEY_VALIDATION_EMPTY_COMMUTER_PERIOD_END_DATE_BEFORE_START_DATE, null));
             return false;
        }

        CommuterDataService commuterDataService = TimeTrackingWebApplication.getService(CommuterDataService.class);
        List<CommuterData> allCommuterDataForEmployee = commuterDataService.getAllCommuterDataForEmployee(model.getEmployee().getId());
        for (CommuterData commuterDataEntry : allCommuterDataForEmployee) {
            TimePeriod newTimePeriod = new TimePeriod(model.getStartDate(), model.getEndDate());
            TimePeriod existingTimePeriod = new TimePeriod(commuterDataEntry.getStartDate(), commuterDataEntry.getEndDate());

            if (CalendarUtils.areTimePeriodOverlapping(newTimePeriod, existingTimePeriod)) {
                feedbackPanel.error(Localizer.get().getString(RESOURCE_KEY_VALIDATION_EMPTY_COMMUTER_PERIOD_OVERLAPPING, null));
                return false;
            }
        }

        return true;
    }

    // TODO: make it transactional
    private void save() {
        model.populateDBModelFromFields();
        CommuterDataService commuterDataService = TimeTrackingWebApplication.getService(CommuterDataService.class);
        commuterDataService.saveDBModel(model.getDBModel());

        // Update worklogs
        WorkLogService workLogService = TimeTrackingWebApplication.getService(WorkLogService.class);
        Collection<WorkLog> workLogs = workLogService.loadWorkLogForTimeIntervalAndEmployee(model.getEmployee(), model.getStartDate(), model.getEndDate());
        for (WorkLog workLog : workLogs) {
            workLog.setIsCommuter(true);
        }
        workLogService.bulkSaveOrUpdateDBModels(workLogs);
    }
}
